<template>
  <li class="item flex items-center"
    :class="[(checkType(dataItem) === 'Object' || checkType(dataItem) === 'Array')?'clickable' : '']"
    @click.stop="select(dataName, checkType(dataItem))">
    <!-- 文件夹📁图标 -->
    <span class="icon type-ref"
      :class="[(checkType(dataItem) === 'Object' || checkType(dataItem) === 'Array')?'platformicon icon_wenjianjia' : '']"></span>
    <!-- 名称 -->
    <span>{{dataName}}</span><span style="color: #fff;">:</span>
    <!-- 数据和操作 -->
    <div class="operation-list">
      <!-- 编辑状态 -->
      <div class="op-item flex"
        v-if="editing">
        <input ref="editInput"
          class="edit-input"
          :class="{error: !valueValid}"
          type="text"
          v-model="editedValue"
          @click.stop
          @keydown.esc.capture.stop.prevent="cancelEdit()"
          @keydown.enter="submitEdit()">
        <span v-if="valueValid"
          class="flex items-center"
          style="margin-left:0px;">
          <button title="取消"
            @click.stop="cancelEdit">
            <a-icon type="close-circle"
              theme='filled'
              style="font-size:14px;" />
          </button>
          <button title="保存"
            @click.stop="submitEdit">
            <a-icon type="save"
              theme='filled'
              style="font-size:14px;" />
          </button>
        </span>
        <span v-else
          class="flex items-center"
          style="color:#ff6320; margin-left: 6px;">
          <a-icon type="warning"
            theme='filled'
            style="font-size:14px;" />
        </span>
      </div>
      <!-- 默认状态 -->
      <div class="op-item default-status flex items-center"
        v-else>
        <span v-if="checkType(dataItem) === 'Object'"
          class="type-ref type-object">{{checkType(dataItem)}}{{(Object.keys(dataItem).length === 0)?" (empty)":""}}</span>
        <span v-else-if="checkType(dataItem) === 'Array'"
          class="type-ref type-array">{{checkType(dataItem)}}[{{dataItem.length}}]</span>
        <span v-else-if="checkType(dataItem) === 'Null'"
          class="Null">null</span>
        <span v-else-if="checkType(dataItem) === 'Undefined'"
          class="Undefined">undefined</span>
        <span v-else
          class="value"
          :title="dataItem"
          :class="[checkType(dataItem)]">{{dataItem}}</span>
        <button title="编辑"
          @click.stop="openEdit">
          <a-icon type="edit"
            theme='filled'
            style="font-size:14px;" />
        </button>
        <button title="添加属性"
          v-if="!isBasic(dataItem)"
          @click.stop="addState">
          <a-icon type="plus-circle"
            theme='filled'
            style="font-size:14px;" />
        </button>
        <button title="删除"
          @click.stop="deleteState">
          <a-icon type="delete"
            theme='filled'
            style="font-size:14px;" />
        </button>
      </div>
    </div>
  </li>

</template>
<script>
import { isPlainObject, isBasic, parse, transformSpecialTokens } from './util'
import mixins from './mixins'
import { Icon } from 'ant-design-vue'

// https://cn.vuejs.org/v2/style-guide/#组件-实例的选项的顺序-推荐
export default {
  name: 'VuexItem',
  mixins: [mixins],
  components: {
    [Icon.name]: Icon
  },
  model: {},
  props: ['dataItem', 'path', 'dataName'],
  data() {
    return {
      editing: false,
      editedValue: ''
    }
  },
  computed: {
    isShow({ dataItem }) {
      return isPlainObject(dataItem)
    },
    valueValid() {
      try {
        parse(transformSpecialTokens(this.editedValue, false))
        return true
      } catch (e) {
        return false
      }
    }
  },
  watch: {},
  created() {},
  mounted() {},
  beforeDestroy() {},
  methods: {
    isBasic,
    // 选中某一个value
    select(key, type) {
      let keys = ['Object', 'Array']
      if (keys.includes(type)) {
        this.$emit('select', key)
      }
    },
    addState() {
      this.select(this.dataName, this.checkType(this.dataItem))
      this.$emit('open-add')
    },
    deleteState() {
      this.$store.dispatch('cmlpanel/DELETE_VUEX_BY_PATH', {
        path: this.path,
        name: this.dataName
      })
    },

    submitEdit() {
      if (this.valueValid) {
        const value = transformSpecialTokens(this.editedValue, false)
        this.$store.dispatch('cmlpanel/CHANGE_VUEX_BY_PATH', {
          path: this.path,
          name: this.dataName,
          value: parse(value, true)
        })
        this.editing = false
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.item {
  display: flex;
  align-items: center;
  overflow: hidden;

  width: 100%;
  height: 20px;
  padding-left: 10px;
  border-bottom: 1px solid rgba(66, 66, 66, 0.5);

  color: #24e0f1;

  white-space: nowrap;
  text-overflow: ellipsis;
}
.operation-list {
  display: flex;
  align-items: center;
}
.op-item {
  margin-left: 5px;
}
.type-ref {
  padding-left: 5px;

  color: #c1fffb;

  opacity: 0.8;

  &:hover {
    opacity: 1;
  }
}
.icon {
  display: inline-block;

  width: 14px;
  margin-right: 4px;
  padding: 0;

  font-size: 14px;
  line-height: 1;
  &.iconfont {
    cursor: pointer;
  }
}
.value {
  padding-left: 5px;
}
.Boolean {
  color: rgb(143, 114, 250);
}
.Number {
  color: #f0a30d;
}
.String {
  color: #d65445;
  &:before {
    content: '"';
  }
  &:after {
    content: '"';
  }
}
.Undefined,
.Null {
  padding-left: 5px;

  color: #b5bec9;
}
.edit-input {
  height: 18px;
  margin-right: 6px;
  padding: 2px 5px;
  border: none;
  border-radius: 2px;

  color: #c1fffb;
  background-color: #899a9a;

  font-family: Menlo, Monaco, 'Courier New', monospace;
  font-size: 12px;
  line-height: 1;
}

button {
  display: flex;
  align-items: center;
  justify-content: center;

  width: 18px;
  height: 18px;
  margin-left: 6px;
  border: none;
  border-radius: 2px;

  color: #ffffffb5;
  background: transparent;
  &:hover {
    color: #fff;
    background-color: #5f7177b3;
  }
}
.flex {
  display: flex;
}
.justify-center {
  justify-content: center;
}
.items-center {
  align-items: center;
}
.error {
  box-shadow: 0 0 2px 1px inset #ff6320;
}
.default-status button {
  display: none;
}
.item:hover {
  .default-status button {
    display: block;
  }
}
</style>
